package com.desginer;

import javax.transaction.InvalidTransactionException;
import java.util.UUID;

public class _29_TransactionMockTest {

    static class IdGenerator{

        public static String generateTransactionId(){

            return UUID.randomUUID().toString();
        }
    }

    static class RedisDistributedLock{

        public static RedisDistributedLock getSingletonIntance(){

            return new RedisDistributedLock();
        }

        public static boolean lockTransction(String id){
            return System.currentTimeMillis() % 2 == 0 ? true : false;
        }

        public static void unlockTransction(String id){}
    }

    class WalletRpcService{
        public String moveMoney(String id, Long buyerId, Long sellerId, Double amount){
            return UUID.randomUUID().toString().replaceAll("-","");
        }
    }
    public class Transaction {
        private String id;
        private Long buyerId;
        private Long sellerId;
        private Long productId;
        private String orderId;
        private Long createTimestamp;
        private Double amount;
        private Integer status;
        private String walletTransactionId;


        // ...get() methods...

        public Transaction(String preAssignedId, Long buyerId, Long sellerId, Long productId, String orderId) {
            if (preAssignedId != null && !preAssignedId.isEmpty()) {
                this.id = preAssignedId;
            } else {
                this.id = IdGenerator.generateTransactionId();
            }
            if (!this.id.startsWith("t_")) {
                this.id = "t_" + preAssignedId;
            }
            this.buyerId = buyerId;
            this.sellerId = sellerId;
            this.productId = productId;
            this.orderId = orderId;
            this.status = 1;
            this.createTimestamp = System.currentTimeMillis();
        }

        public boolean isExpire(){//封装，修改过期先决条件
            long executionInvokedTimestamp = System.currentTimeMillis();
            if(executionInvokedTimestamp - createTimestamp > 14){
                return true;
            }
            return false;
        }

        public boolean execute() throws Exception {
            if (buyerId == null || sellerId == null || amount < 0.0){
                throw new Exception("error");
            }
            if (status == 1) return true;
            boolean isLocked = false;
            try {
                isLocked = RedisDistributedLock.getSingletonIntance().lockTransction(id);
                if (!isLocked) {
                    return false; // 锁定未成功，返回false，job兜底执行
                }
                if (status == 1) return true; // double check

                if (isExpire()) {
                    this.status = 2;
                    return false;
                }
                WalletRpcService walletRpcService = new WalletRpcService();
                String walletTransactionId = walletRpcService.moveMoney(id, buyerId, sellerId, amount);
                if (walletTransactionId != null) {
                    this.walletTransactionId = walletTransactionId;
                    this.status = 1;
                    return true;
                } else {
                    this.status = 3;
                    return false;
                }
            } finally {
                if (isLocked) {
                    RedisDistributedLock.getSingletonIntance().unlockTransction(id);
                }
            }
        }
    }
}
